const gulp = require('gulp'),
       jq = require('jquery'),
       changed = require('gulp-changed'),    // 只编译改动过的文件
       htmlmin = require('gulp-htmlmin'),    // html 压缩
       sass = require('gulp-sass'),          // 编译 sass
       autofx = require('gulp-autoprefixer'),    // css 浏览器前缀补全
       cleanCSS = require('gulp-clean-css'),     // 压缩 css
       eslint = require('gulp-eslint'),          // js 代码检查
       babel = require('gulp-babel'),            // 编译 es6 代码
       uglify = require('gulp-uglify'),          // js 压缩
       imagemin = require('gulp-imagemin'),      // 图片压缩
       cache = require('gulp-cache'),            // 图片缓存，图片替换了才压缩
       runSequence = require('run-sequence'),    // 设定同步异步执行任务
       md5 = require('gulp-md5-assets'),         // 添加 md5
       concat = require('gulp-concat'),          // 合并文件
       del = require('del'),                     // 删除文件
       browserSync = require('browser-sync').create(),   // 静态服务器
       reload = browserSync.reload,
       wiredep = require('wiredep').stream,

       config = require('./config/pluginConfig');    // 引入插件的配置

// 自动添加第三方插件到index.html
gulp.task('add-plugins-index', () => {
    return gulp
        .src('./app/index.html')
        .pipe(wiredep({
            optional: 'configuration',
            goes: 'here'
        }))
        .pipe(gulp.dest('./dev'));
})

// 转移 html --> (/dev)
gulp.task('move-html', () => {
    return gulp
        .src('./app/**/*.html')
        .pipe(changed('./dev'))
        .pipe(gulp.dest('./dev'));
})

// 压缩 html --> (/build)
gulp.task('minify-html', ['move-html'], () => {
    return gulp
        .src('./dev/**/*.html')
        .pipe(htmlmin(config.htmlmin))
        .pipe(gulp.dest('./build'))
        .pipe(md5(10));
})

// 编译 sass --> (/dev)
gulp.task('sass', () => {
    return gulp
        .src('./app/styles/**/*.scss')
        .pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError))
        .pipe(autofx(config.autofx))
        .pipe(gulp.dest('./dev/styles'))
        .pipe(reload({stream: true}));
})

// 压缩 css --> (/build)
gulp.task('minify-css', ['sass'], () => {
    return gulp
        .src('./dev/styles/**/*.css')
        .pipe(cleanCSS(config.cleanCSS))
        .pipe(gulp.dest('./build/styles'))
        .pipe(md5(10, './build/**/*.html'));   // 查找对应文件，替换为添加md5的文件名
})

// 编译 js --> (/dev)
gulp.task('babel-js', () => {
    return gulp
        .src('./app/scripts/**/*.js')
        .pipe(eslint())
        .pipe(eslint.format())  // 错误格式化输出
        .pipe(changed('./dev/scripts'))
        .pipe(babel({
            presets: ['es2015', 'stage-1']
        }))
        .pipe(gulp.dest('./dev/scripts'))
        .pipe(reload({stream: true}));
})

// 压缩js --> (/build)
gulp.task('minify-js', ['babel-js'], () => {
    return gulp
        .src('./dev/scripts/**/*.js')
        .pipe(uglify(config.uglify))
        .pipe(gulp.dest('./build/scripts'))
        .pipe(md5(10, './build/**/*.html'));
})

// 转移图片 --> (/dev)
gulp.task('move-img', () => {
    return gulp
        .src('./app/imgs/**/*.{png,jpg,gif,ico}')
        .pipe(changed('./dev/imgs'))
        .pipe(gulp.dest('./dev/imgs'))
        .pipe(reload({stream: true}));
})

// 压缩图片 --> (/build)
gulp.task('minify-img', ['move-img'], () => {
    return gulp
        .src('./dev/imgs/**/*.{png,jpg,gif,ico}')
        .pipe(cache(imagemin({
            progressive: true,
            optimizationLevel: 5
        })))
        .pipe(gulp.dest('./build/imgs'))
        .pipe(md5(10, './build/**/*.{css,js,html,json}'));
})

// json 转移 --> (/dev)
gulp.task('move-json', () => {
    return gulp
        .src('./app/_data/*.json')
        .pipe(gulp.dest('./dev/_data'))
        .pipe(reload({stream: true}));
})

// json 转移至 build --> (/build)
gulp.task('build-json', () => {
    return gulp
        .src('./app/_data/*.json')
        .pipe(gulp.dest('./build/_data'))
        .pipe(md5(10, './build/**/*.js'));
})

// 转移 libs 插件 (libs 中引入的都是压缩后的文件)
// gulp.task('move-libs-dev', () => {
//     return gulp.src('./bower_components/**/*')
//         .pipe(gulp.dest('./dev/verdors'));
// })
//
// gulp.task('move-libs-build', () => {
//     return gulp.src('./bower_components/**/*')
//         .pipe(gulp.dest('./build/verdors'))
//         .pipe(md5(10, './build/**/*.html'))
// })

// 清空文件夹
gulp.task('clean-dev', (cb) => {
    return del(['./dev/**/*'], cb);
})

gulp.task('clean-build', (cb) => {
    return del(['./build/**/*'], cb);
})

// 命令行命令
/*
    编译
    清空 /dev 文件夹，将 html、编译后的css、编译后的js、libs中文件、图片、json文件引入
*/
gulp.task('dev', (cb) => {
    // [] 中任务是并行的，其他按照先后顺序执行
    runSequence('clean-dev', 'add-plugins-index', 'move-html', [
        'sass', 'babel-js'
    ], 'move-img', 'move-json', cb)
})

// 测试执行
gulp.task('run', ['dev'], () => {
    browserSync.init({      // 启动Browsersync服务
        server: {
            baseDir: './dev',   // 启动服务的目录 默认 index.html
            index: 'index.html' // 自定义启动文件名
        },
        open: 'external',   // 决定Browsersync启动时自动打开的网址 external 表示 可外部打开 url, 可以在同一 wifi 下不同终端测试
        injectChanges: true // 注入CSS改变
    });

    // 监听文件变化，执行相应任务
    gulp.watch('./app/styles/**/*.scss', ['sass']);
    gulp.watch('./app/scripts/**/*.js', ['babel-js']);
    gulp.watch('./app/imgs/**/*.{png,jpg,gif,ico}', ['move-img']);
    gulp.watch('./app/_data/*.json', ['move-json']);
    gulp.watch('./app/**/*.html', ['move-html']).on('change', reload);
})

/*
    压缩输出
    清空 /build 文件夹，压缩html、压缩css、压缩js、引入libs中文件、引入压缩后图片、引入json，同时添加MD5
*/
gulp.task('build', (cb) => {
    runSequence('clean-build', 'minify-html', [
        'minify-css', 'minify-js', 'move-libs-build'
    ], 'minify-img', 'build-json', cb)
})

// 生产版本测试
gulp.task('build-test', ['build'], () => {
    // 生产版本不允许更改文件后实时编译输出
    browserSync.init({
        server: {
            baseDir: './build'
        },
        open: 'external'
    });
})
